package com.maint.m

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

/**
 * WebSocketService 使用示例类
 * 展示如何在Activity中使用封装后的WebSocket服务，针对实际业务场景优化
 */
class WebSocketUsageExample : AppCompatActivity() {

    // 业务编码常量定义
    private object BusinessCode {
        const val CONFIRM = 0              // 确认操作
        const val WORK_TICKET_RECOGNIZE = 1  // 工作票识别
        const val WORK_TICKET_TO_CONFIRM = 11 // 工作票识别待确认
        const val SWITCH_STATION_IDENTIFY = 2 // 开关站铭牌识别核对
        const val ELECTRIC_CABINET_IDENTIFY = 3 // 电气柜铭牌识别核对
        const val DEVICE_RECOGNIZE = 4     // 开关、刀闸、地线设备识别
        const val SPECIFY_OPERATION = 5    // 指定操作任务
    }

    private val gson = Gson()

    // 创建WebSocket处理器
    private val webSocketHandler = object : SimpleWebSocketHandler {
        override fun onMessageReceived(type: WebSocketMessageType, message: String) {
            Log.d("WebSocketExample", "收到消息: $message")
            
            try {
                // 解析消息，获取业务编码
                val messageData = parseMessage(message)
                if (messageData != null) {
                    val businessCode = messageData["business"] as? Number
                    when (businessCode?.toInt()) {
                        BusinessCode.CONFIRM -> {
                            handleConfirmResponse(messageData)
                        }
                        BusinessCode.WORK_TICKET_RECOGNIZE -> {
                            handleWorkTicketRecognize(messageData)
                        }
                        BusinessCode.WORK_TICKET_TO_CONFIRM -> {
                            handleWorkTicketToConfirm(messageData)
                        }
                        BusinessCode.SWITCH_STATION_IDENTIFY -> {
                            handleSwitchStationIdentify(messageData)
                        }
                        BusinessCode.ELECTRIC_CABINET_IDENTIFY -> {
                            handleElectricCabinetIdentify(messageData)
                        }
                        BusinessCode.DEVICE_RECOGNIZE -> {
                            handleDeviceRecognize(messageData)
                        }
                        BusinessCode.SPECIFY_OPERATION -> {
                            handleSpecifyOperation(messageData)
                        }
                        else -> {
                            Log.w("WebSocketExample", "未知业务编码: $businessCode")
                        }
                    }
                }
            } catch (e: Exception) {
                Log.e("WebSocketExample", "解析消息异常: ${e.message}", e)
            }
        }

        override fun onConnectionChanged(connected: Boolean) {
            // 处理连接状态变化
            val status = if (connected) "已连接" else "已断开"
            Log.d("WebSocketExample", "WebSocket连接状态: $status")
            
            // 根据连接状态更新UI或执行相应操作
            updateConnectionUI()
        }

        override fun onError(errorMsg: String) {
            // 处理错误
            Log.e("WebSocketExample", "WebSocket错误: $errorMsg")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_example)
        
        // 初始化其他UI组件
        initUI()
    }

    override fun onResume() {
        super.onResume()
        
        // 注册WebSocket消息处理器
        // 传入this作为上下文，这样可以在Activity销毁时自动清理资源
        WebSocketService.getInstance().registerHandler(webSocketHandler, this)
        
        // 可选：确保WebSocket已连接
        if (!WebSocketService.getInstance().isConnected()) {
            WebSocketService.getInstance().connect()
        }
    }

    override fun onPause() {
        super.onPause()
        
        // 重要：在Activity暂停时注销处理器，避免内存泄漏
        // 注意：如果在registerHandler时传入了Activity作为上下文，
        // 这里可以不手动注销，因为WebSocketService会自动处理
        // 但为了演示完整流程，这里仍然展示如何手动注销
        WebSocketService.getInstance().unregisterHandler(webSocketHandler)
    }

    private fun initUI() {
        // 初始化UI组件...
    }

    private fun updateConnectionUI() {
        // 更新UI以反映连接状态
        // 例如，显示/隐藏连接指示器，启用/禁用相关按钮等
    }

    /**
     * 解析WebSocket消息
     */
    private fun parseMessage(message: String): Map<String, Any>? {
        return try {
            gson.fromJson(message, object : TypeToken<Map<String, Any>>() {}.type)
        } catch (e: Exception) {
            Log.e("WebSocketExample", "解析消息失败: ${e.message}")
            null
        }
    }

    /**
     * 处理确认响应消息
     */
    private fun handleConfirmResponse(messageData: Map<String, Any>) {
        val data = messageData["data"] as? String
        Log.d("WebSocketExample", "收到确认响应: $data")
        if (data == "ok") {
            Log.d("WebSocketExample", "操作已确认")
        }
    }

    /**
     * 处理工作票识别消息
     */
    private fun handleWorkTicketRecognize(messageData: Map<String, Any>) {
        // 检查是否有额外数据
        val additionalData = messageData["data"]
        Log.d("WebSocketExample", "收到工作票识别结果，数据: $additionalData")
        // 执行工作票识别后的逻辑
    }

    /**
     * 处理工作票识别待确认消息
     */
    private fun handleWorkTicketToConfirm(messageData: Map<String, Any>) {
        val instruct = messageData["instruct"] as? Number
        Log.d("WebSocketExample", "工作票识别待确认，指令: $instruct")
        // 重要提示：这里保留Toast以确保用户知道需要确认
        showToast("请确认工作票识别结果")
        // 显示确认对话框或其他交互界面
    }

    /**
     * 处理开关站铭牌识别核对消息
     */
    private fun handleSwitchStationIdentify(messageData: Map<String, Any>) {
        val data = messageData["data"] as? String
        Log.d("WebSocketExample", "开关站铭牌识别结果: $data")
        // 执行识别结果核对逻辑
    }

    /**
     * 处理电气柜铭牌识别核对消息
     */
    private fun handleElectricCabinetIdentify(messageData: Map<String, Any>) {
        val data = messageData["data"] as? String
        Log.d("WebSocketExample", "电气柜铭牌识别结果: $data")
        // 执行识别结果核对逻辑
    }

    /**
     * 处理设备识别消息（开关、刀闸、地线）
     */
    private fun handleDeviceRecognize(messageData: Map<String, Any>) {
        val data = messageData["data"]
        when (data) {
            is List<*> -> {
                Log.d("WebSocketExample", "设备识别结果: ${data.joinToString()}, 共${data.size}个设备")
            }
            else -> {
                Log.d("WebSocketExample", "设备识别结果: $data")
            }
        }
    }

    /**
     * 处理指定操作任务消息
     */
    private fun handleSpecifyOperation(messageData: Map<String, Any>) {
        val data = messageData["data"] as? String
        Log.d("WebSocketExample", "指定操作任务: $data")
        // 执行操作任务
    }

    private fun showToast(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

    /**
     * 发送确认消息
     */
    private fun sendConfirmMessage() {
        WebSocketService.getInstance().sendStructuredMessage(
            business = BusinessCode.CONFIRM,
            data = "ok",
            showToast = true,
            context = this
        )
    }

    /**
     * 发送工作票识别请求
     */
    private fun sendWorkTicketRecognizeRequest() {
        WebSocketService.getInstance().sendStructuredMessage(
            business = BusinessCode.WORK_TICKET_RECOGNIZE,
            showToast = true,
            context = this
        )
    }

    /**
     * 发送工作票识别确认指令
     */
    private fun sendWorkTicketConfirmInstruction(instruction: Int) {
        // 对于特殊格式的消息，使用sendMessage发送完整的JSON字符串
        val message = "{\"business\": 11, \"instruct\": $instruction}"
        WebSocketService.getInstance().sendMessage(
            message = message,
            showToast = true,
            context = this
        )
    }

    /**
     * 发送指定操作任务
     */
    private fun sendSpecifyOperationTask(taskDescription: String) {
        WebSocketService.getInstance().sendStructuredMessage(
            business = BusinessCode.SPECIFY_OPERATION,
            data = taskDescription,
            showToast = true,
            context = this
        )
    }

    /**
     * 发送电气柜铭牌识别核对
     */
    private fun sendElectricCabinetIdentify(cabinetName: String) {
        WebSocketService.getInstance().sendStructuredMessage(
            business = BusinessCode.ELECTRIC_CABINET_IDENTIFY,
            data = cabinetName,
            showToast = true,
            context = this
        )
    }

    /**
     * 发送设备识别请求（开关、刀闸、地线）
     */
    private fun sendDeviceRecognizeRequest() {
        val devices = listOf("开关", "刀闸", "地线")
        WebSocketService.getInstance().sendStructuredMessage(
            business = BusinessCode.DEVICE_RECOGNIZE,
            data = devices,
            showToast = true,
            context = this
        )
    }

    /**
     * 手动断开连接
     */
    private fun disconnectWebSocket() {
        WebSocketService.getInstance().disconnect()
    }

    /**
     * 检查连接状态
     */
    private fun checkConnectionStatus() {
        val isConnected = WebSocketService.getInstance().isConnected()
        showToast("WebSocket ${if (isConnected) "已连接" else "未连接"}")
    }

    /**
     * 演示如何使用所有消息发送方法
     */
    private fun demonstrateAllMessageTypes() {
        // 1. 发送确认消息
        sendConfirmMessage()
        
        // 2. 发送工作票识别请求
        sendWorkTicketRecognizeRequest()
        
        // 3. 发送工作票确认指令
        sendWorkTicketConfirmInstruction(1)
        
        // 4. 发送指定操作任务
        sendSpecifyOperationTask("合寓开关站墅园H793线宝利德二分线由线路检修改为运行")
        
        // 5. 发送电气柜铭牌识别核对
        sendElectricCabinetIdentify("墅园H793线宝利德二分线")
        
        // 6. 发送设备识别请求
        sendDeviceRecognizeRequest()
    }
}

/**
 * 使用说明：
 * 
 * 1. 业务编码对应说明：
 *    - 0: 确认操作
 *    - 1: 工作票识别
 *    - 11: 工作票识别待确认（含instruct参数）
 *    - 2: 开关站铭牌识别核对
 *    - 3: 电气柜铭牌识别核对
 *    - 4: 开关、刀闸、地线设备识别
 *    - 5: 指定操作任务
 * 
 * 2. 消息格式：
 *    - 所有消息必须包含business字段
 *    - 根据业务类型不同，可能包含data或instruct等字段
 *    - data字段可以是字符串、数组或对象
 * 
 * 3. 使用步骤：
 *    - 创建WebSocket处理器：实现SimpleWebSocketHandler接口
 *    - 生命周期管理：在onResume注册，onPause注销
 *    - 消息处理：根据业务编码分发到不同的处理方法
 *    - 消息发送：使用封装的方法发送对应业务类型的消息
 * 
 * 4. 示例消息：
 *    - 确认消息: {"business": 0, "data": "ok"}
 *    - 工作票识别: {"business": 1}
 *    - 工作票待确认: {"business": 11, "instruct": 1}
 *    - 指定操作任务: {"business": 5, "data": "操作描述"}
 *    - 电气柜识别: {"business": 3, "data": "设备名称"}
 *    - 设备识别: {"business": 4, "data": ["开关","刀闸","地线"]}
 */